package com.softWang.common.aop;

import com.softWang.common.exception.LogicException;
import com.softWang.common.response.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;

import com.softWang.common.exception.ErrorCode;


/**
 * 自定义异常处理器
 *
 */
@RestControllerAdvice
public class DefaultExceptionHandler {
    public static Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class);
    /**
     * 请求方式不支持
     */
    @ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
    public ResponseResult handleException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return ResponseResult.sysError("不支持' " + e.getMethod() + "'请求");
    }

    /**
     * 业务逻辑异常
     * @param e
     * @return
     */
    @ExceptionHandler(LogicException.class)
    public ResponseResult logicHandlers(LogicException e) {
        log.error(e.getMessage(), e);
        return ResponseResult.failure(ErrorCode.ERROR_LOGIC).appendMessage(e.getMessage());
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseResult errorHandler(MethodArgumentNotValidException e) {
        String errorMsg = "";
        List<ObjectError> errorList = e.getBindingResult().getAllErrors();
        for (ObjectError error : errorList) {
            String msg = error.getDefaultMessage();
            errorMsg += ("【" + msg + "】,");
        }
        errorMsg = errorMsg.substring(0, errorMsg.length() - 1);
        log.error("参数错误：" + errorMsg);
        return ResponseResult.failure(ErrorCode.NOTNULL_PARAMS).appendMessage(errorMsg);
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResponseResult validationHandler(ConstraintViolationException e) {
        StringBuilder message = new StringBuilder("Invalid Request Parameters: ");

        for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
            message.append(constraintViolation.getMessage())
                    .append(", received value is '")
                    .append(constraintViolation.getInvalidValue())
                    .append("'; ");
        }
        return ResponseResult.failure(ErrorCode.NOTNULL_PARAMS).appendMessage(message.toString());
    }

    @ExceptionHandler(value = BindException.class)
    public ResponseResult validationHandlers(BindException e) {
        String errorMsg = "";
        List<ObjectError> errorList = e.getBindingResult().getAllErrors();
        for (ObjectError error : errorList) {
            String msg = error.getDefaultMessage();
            errorMsg += ("【Invalid Request Parameters:" + msg + "】,");
        }
        errorMsg = errorMsg.substring(0, errorMsg.length() - 1);
        log.error("参数错误：" + errorMsg);
        return ResponseResult.failure(ErrorCode.NOTNULL_PARAMS).appendMessage(errorMsg);
    }

    /**
     * SpringSecurity抛出异常但AccessDeniedHandler不生效
     * 全局异常中捕获AccessDeniedException再抛出就可以被AccessDeniedHandler捕获到了
     * @param e
     * @throws AccessDeniedException
     */
    @ExceptionHandler(AccessDeniedException.class)
    public void accessDeniedException(AccessDeniedException e) throws AccessDeniedException {
        throw e;
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult handleException(Exception e) {
        log.error(e.getMessage(), e);
        return ResponseResult.sysError("服务器错误，请联系管理员:" + e.getMessage());
    }


}
